
#include "stm32f10x_conf.h"
#include "aero_conf.h"
#include "main.h"

/* Private variables ---------------------------------------------------------*/
static __IO uint32_t TimingDelay;

/* Private function prototypes -----------------------------------------------*/
void Delay(__IO uint32_t nTime);

u16 Get_adc(u8 ch);

unsigned char oledGram[128][8];

void NVIC_Configuration(void);

  __IO uint16_t CCR1_Val = 37309;
  __IO uint16_t CCR2_Val = 27309;
  __IO uint16_t CCR3_Val = 13654;
  __IO uint16_t CCR4_Val = 6826;

//判断是否有电平跳变，将脉冲信号转成电平信号
uint16_t latchVT;
uint16_t mlongVT;
uint16_t longVT;
vtState hsCs;

uint16_t tim3ItFlag;//指示中断接收
int vtLatchValue;

int gsExCnt;//export人数统计
int gsImCnt;//import人数统计


typedef enum{
  IDLE,
  FRIIMPORT,
  SECIMPORT,
  FRIEXPORT,
  SECEXPORT,
  IMFATTY,
  EXFATTY,
  ERR,
}STATE;

eventCode aero_checkPulse(uint16_t tmpVT);
void upDateValue(STATE current_state);
uint16_t aero_ledFlash(uint16_t led_on);

int main(void)
{
//  uint16_t ADCConvertedValue;
  SystemInit();
  aero_InitRcc();
  NVIC_Configuration();
  aero_InitUart();
  aeroBsp_InitMco();
  aero_InitLed();
  aero_InitAdc1();
  aero_InitOled();
  aero_InitTe();
  aero_InitVt();

      
  aeroTim3ModeConfig();
  
  
  ClrCsPin;
  OledInit();
  OledClear();
  OledShowString(18,2,"12.12",1);
  OledShowString(6,20,"DD>",1);
  OledShowString(6,36,"CC>",1);
  OledRefreshGram();	

//  char tcmd[20] = {0x31,0x32,0x33};

  if (SysTick_Config(SystemCoreClock / 1000))
  { 
    /* Capture error */ 
    while (1);
  }
  
  int k = 2;
  int led_on = 1;
  uint16_t tmpVT;
  eventCode ec;
  uint16_t vtNeg;// vt监测到下降沿
//  OledShowNum(72,36,k,3,12,1);

  gsExCnt = 0;
  gsImCnt = 0;
  vtLatchValue = 0x3;
  tim3ItFlag = 0;
    
    longVT = 0x0;//初始都为低
    mlongVT = 0x0;
    latchVT = 0x0;//初始都为低
    STATE current_state = IDLE;

    initHsState();

    while(1){
        tmpVT = aero_ReadVt();
        ec = aero_checkPulse(tmpVT);
        aero_hsProcess(ec);
        upDateValue( current_state );

        k++;
        if ( k== K_MAX ){
            k = 0;
            OledShowNum(72,20,gsImCnt,3,12,1);
            OledShowNum(72,36,gsExCnt,3,12,1);            
            OledShowNum(42,48,tmpVT,1,12,1);
            OledShowNum(72,48,longVT,1,12,1);            
            OledRefreshGram();
            led_on = aero_ledFlash(led_on);	
        }
    }
}

// int main(void)
// {
//   uint16_t ADCConvertedValue;
//   SystemInit();
// //  SystemCoreClockUpdate();
//   aero_InitRcc();
//   NVIC_Configuration();
//   aero_InitUart();
//   aeroBsp_InitMco();
//   aero_InitLed();
//   aero_InitAdc1();
//   aero_InitOled();
//   aero_InitTe();
//   aero_InitVt();
//   aeroTim3ModeConfig();
  
  
//   ClrCsPin;
//   OledInit();
//   OledClear();
//   OledShowString(18,2,"12.12",1);
//   OledShowString(6,20,"DD>",1);
//   OledShowString(6,36,"CC>",1);
//   OledRefreshGram();	

//   char tcmd[20] = {0x31,0x32,0x33};

//   if (SysTick_Config(SystemCoreClock / 1000))
//   { 
//     /* Capture error */ 
//     while (1);
//   }
  
//   int i;
//   int k;
//   int led_on;
//   led_on = 1;
//   uint16_t tmpVt;
  
//   OledShowNum(72,36,k,3,12,1);

//   gsExCnt = 0;
//   gsImCnt = 0;

//   vtLatchValue = 0x3;
//   STATE current_state = IDLE;
  
//   tim3ItFlag = 0;
  
//   while(1){
    
//     upDateValue( current_state );
//     k++;
//     if ( k== 999 )
//       k = 0;
//     OledShowNum(72,36,k,3,12,1);
//     OledRefreshGram();	
//     if( led_on )
//     {
//       GPIO_ResetBits(GPIOB,GPIO_Pin_11);
//       led_on = 0;
//     }
//     else
//     {
//       GPIO_SetBits(GPIOB,GPIO_Pin_11);  
//       led_on = 1;
//     }
// //    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
// //      ADCConvertedValue = ADC_GetConversionValue(ADC1);
// //    
// //    for(i=0;i<3;i++){
// //      aero_UartTxByte(UART_DBG,tcmd[i]);
// //    }
// //    Delay(500);
// //      DBG_printf(UART_DBG,"ad Value %x\r\n",Get_adc(1));
//   }
// }

/**
*/
u16 Get_adc(u8 ch)
{
        /* ADC1 regular channel14 configuration */ 
  ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5);
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

      while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
      return ADC_GetConversionValue(ADC1);
  
}
/**
  * @brief  Inserts a delay time.
  * @param  nTime: specifies the delay time length, in milliseconds.
  * @retval None
  */
void Delay(__IO uint32_t nTime)
{ 
  TimingDelay = nTime;

  while(TimingDelay != 0);
}

/**
  * @brief  Decrements the TimingDelay variable.
  * @param  None
  * @retval None
  */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  { 
    TimingDelay--;
  }
}

/**
  * @brief  Configure the nested vectored interrupt controller.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;// | TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
}

/*
HIGH时为IDLE，没有人出入
从高位到低位的 0值变换判断为 进计数
从低位到高位的 0值变化判断为 出计数

bit 1  bit 0 

11 01 10 11 进
3   1  2  3     一个标准完整周期
11 01 00 10 11 进
3   1  0  2  3  一个庞型完整周期

11 10 01 11 出
3  2   1  3     一个标准“出”完整周期
11 10 00 01 11 出
3  2   0  1  3  一个胖型“出”完整周期
*/

void upDateValue(STATE current_state)
{
//    int vtValue;
    int imCntFlag = 0;
    int exCntFlag = 0;
    int valueChanged = 0;

    //默认启动后vtLatchValue 为3
    if( longVT == vtLatchValue ){
        valueChanged = 0;
    }
    else{
        vtLatchValue = longVT;
        valueChanged = 1;
    }

    //数值有变化时启动 状态机，这样状态机中的跳变只发生一次
    if( valueChanged == 1){
        switch( current_state ){
            case IDLE:{
                switch( vtLatchValue ){
                    case 0:current_state = IDLE;break;//太快了分辨不出方向
                    case 1:current_state = FRIIMPORT;break;
                    case 2:current_state = FRIEXPORT;break;
                    case 3:current_state = IDLE;break;
                    default:current_state = IDLE;
                }
                break;
            }
      
            case FRIIMPORT:{
                switch( vtLatchValue ){
                    // case 0:current_state = IMFATTY;break;
                    // case 1:current_state = PREIMPORT;break;        
                    case 2:current_state = SECIMPORT;break;
                    default:current_state = IDLE;
                }        
                break;
            }
            
            case IMFATTY:{
                switch( vtLatchValue ){
                    case 1:current_state = FRIIMPORT;break;        
                    case 2:current_state = SECIMPORT;break;
                    default:current_state = IDLE;
                }                  
                break;
            }
            
            case SECIMPORT:{
                switch( vtLatchValue ){
                    // case 1:current_state = PREIMPORT;break;
                    case 3:current_state = IDLE;imCntFlag = 1;break;
                    default:current_state = IDLE;
                }
                break;
            }

            case FRIEXPORT:{
                switch( vtLatchValue ){
//                    case 0:current_state = EXFATTY;break;
                    case 1:current_state = SECEXPORT;break;
                    // case 2:current_state = PREEXPORT;break;
                    // case 3:current_state = IDLE;break;
                    default:current_state = IDLE;
                }                
                break;
            }

            case EXFATTY:{
                switch(  vtLatchValue ){
                    case 1:current_state = SECEXPORT;break;
                    default:current_state = IDLE;
                }
            }
            
            case SECEXPORT:{
                switch(  vtLatchValue ){
                    // case 0: current_state = EXFATTY;break;
                    // case 2: current_state = PREEXPORT;break;
                    case 3: current_state = IDLE; exCntFlag = 1; break;
                    default: current_state = IDLE;
                }
            }
            default:current_state = IDLE;
        }
    }

    if ( imCntFlag == 1 )
        gsImCnt++;
        
    if ( exCntFlag == 1 )
        gsExCnt++;
}


/*
    检查读回的值，对事件码赋值,
*/
eventCode aero_checkPulse(uint16_t tmpVT)
{
    eventCode ret;

    switch( latchVT ){
        case 0:
            if( tmpVT > 0 )
                ret = EV_HAVEHIGH;
            else
                ret = EV_ALLZERO;
            break;
        case 1:
            if ( tmpVT == 0 ){
                ret = EV_NEGEDGE;
            }
            else
                ret = EV_HAVEHIGH;
            break;
        case 2:
            if ( tmpVT == 0){
                ret = EV_NEGEDGE;
            }
            else
                ret = EV_HAVEHIGH;
            break;
        case 3:
            if ( tmpVT == 3)
                ret = EV_HAVEHIGH;
            else{
                ret = EV_NEGEDGE;
            }
            break;
        default:
            break;
    }

    if( tmpVT != latchVT ){
        mlongVT = latchVT;    
        latchVT = tmpVT;
    }
    return ret;
}

uint16_t aero_ledFlash(uint16_t led_on)
{
    if( led_on ){
        GPIO_ResetBits(GPIOB,GPIO_Pin_11);
        led_on = 0;
    }
    else{
        GPIO_SetBits(GPIOB,GPIO_Pin_11);  
        led_on = 1;
    }

    return led_on;
}